#inlcude<iostream>
#include<queue>

using namespace std;

#define NUM 5

template<class T>
class ThreadPool {
public:
    ThreadPool(int num = NUM) : _num(num) {
        pthread_mutex_init(&_lock, nullptr);
        pthread_cond_init(&_cond, nullptr)

        pthread_t tid;
        for (int i = 0; i < _num; ++i) {
            pthread_create(&tid, nullptr, Routine, (void*)this);

            pthread_detach(tid);
        }
    }
    void Wait() {
        pthread_cond_wait(&_cond, &_lock);
    }
    void Wake() {
        pthread_cond_signal(&_cond);
    }
    static void* Routine(void* arg) {
        ThreadPool* self = static_cast<ThreadPool*>(arg);
        while (true) {
            self->LockQueue();
            while (self->IsEmpty()) {   //不用if的原因是怕一些会引起变量改变的问题，循环检测更安全
                self->Wait();
            }
            T t;
            self->Pop(t);
            self->UnlockQueue();

            t.Run(); //执行任务
        }

    }
    void LockQueue() {
        pthread_mutex_lock(&_lock);
    }
    void UnlockQueue() {
        pthread_mutex_unlock(_lock);
    }
    bool IsEmpty() {
        return _task_queue.empty();
    }

    void Push(const T& task) {
        LockQueue();
        _task_queue.push(task);
        UnlockQueue();

        Wake();
    }
    void Pop(T& task) {
        LockQueue();
        task = _task_queue.front();
        _task_queue.pop();
        UnlockQueue();
    }
    ~ThreadPool() {
        pthread_mutex_destroy(&_lock);
        pthread_cond_destroy(&_cond);
    }
private:
    int _num;   //线程数量
    queue<T> _task_queue;
    pthread_mutex_t _lock;
    pthread_cond_t _cond;
}